﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YJKArchBaseCode.OutWallSearch;
using YJKArchUtils.Utils;
using YJKRevitBase.WinForm;
using YJKRevitView;

namespace YJKRevitArea.AreaSet
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class CmdFireZone : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Execute(ExternalCommandData cmdData, ref string messages, ElementSet elements)
		{
			AreaPlanType types = AreaPlanType.FireCompartmentArea;
			if (SwitchView.SetUsableView(types, cmdData.Application) != Autodesk.Revit.UI.Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			this.doc = cmdData.Application.ActiveUIDocument.Document;
			Selection selection = cmdData.Application.ActiveUIDocument.Selection;
			Common.m_Revit = cmdData;
			Common.m_roomCv = this.GetRoomSeparateLine();
			if (!(this.doc.ActiveView as ViewPlan).AreaScheme.Name.Contains("防火"))
			{
				YJKMessageBox.Show("该命令仅运行于防火分区面积平面。");
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (Common.FilterAreas(this.doc).Count > 0)
			{
				DialogResult dialogResult = YJKMessageBox.Show("当前视图已存在面积对象，是否删除？", MessageBoxButtons.YesNoCancel);
				if (DialogResult.Cancel == dialogResult)
				{
					return Autodesk.Revit.UI.Result.Failed;
				}
				if (DialogResult.Yes == dialogResult)
				{
					foreach (Area area in Common.FilterAreas(this.doc))
					{
						Common.DeleteArea(this.doc, area.Id);
					}
					CmdFireZone.DeleteAreaBorder(this.doc);
				}
			}
			HideWarningAndErroringKit @object = new HideWarningAndErroringKit(new List<string>
			{
				"CreateRamp",
				"Create FireZone By Rooms",
				"TransactionGroup"
			}, HideWarningAndErroringKit.HideKitEnum.HideWarning);
			cmdData.Application.Application.FailuresProcessing += @object.OnFailuresProcessing;
			if (CmdFireZone._hWndRevit == null)
			{
                CmdFireZone._hWndRevit = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			FireZoneForm fireZoneForm = new FireZoneForm(0, 0);
			fireZoneForm.Show(CmdFireZone._hWndRevit);
			FireZoneLableInfo labelInfo = fireZoneForm.m_labelInfo;
			Common.CreateLineStyle(this.doc, "AreaBoundaryLine", labelInfo.m_lineWidth, labelInfo.m_lineColor);
			LinePatternElement linePattern = Common.CreateLinePatternElement(this.doc, "防火分区边界");
			List<WallData> lstOutWallData = new List<WallData>();
			OutWallFilter.Search(this.doc, (this.doc.ActiveView as ViewPlan).Id, ref lstOutWallData, true, true);
			AreaCreator areaCreator = new AreaCreator(cmdData);
			RoomFilter roomFilter = new RoomFilter();
			List<Element> list = new List<Element>();
			do
			{
				if (fireZoneForm.m_drawType != 0)
				{
					try
					{
						int wMsg = 7;
						CmdFireZone.SendMessage(CmdFireZone._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
						list.Clear();
						if (1 == fireZoneForm.m_drawType)
						{
							list = selection.PickElementsByRectangle(roomFilter, "请框选房间生成防火分区").ToList<Element>();
						}
						else
						{
							foreach (Reference reference in selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, roomFilter, "请框选房间生成防火分区"))
							{
								list.Add(this.doc.GetElement(reference));
							}
						}
						if (list.Count == 0)
						{
							continue;
						}
					}
					catch (Autodesk.Revit.Exceptions.OperationCanceledException)
					{
						if (fireZoneForm.m_clickMode)
						{
							fireZoneForm.m_clickMode = false;
							continue;
						}
						if (fireZoneForm.m_clickSetOk)
						{
							fireZoneForm.m_clickSetOk = false;
							if (fireZoneForm.m_refreshExist)
							{
								areaCreator.RefreshFireZoneStyle(this.doc, fireZoneForm.m_labelInfo, linePattern);
							}
							continue;
						}
						fireZoneForm.Close();
						return Autodesk.Revit.UI.Result.Succeeded;
					}
					Result result;
					try
					{
						List<Room> rooms = list.Cast<Room>().ToList<Room>();
						Common.m_WallRangeType = fireZoneForm.m_wallRange;
						areaCreator.CreateFireZoneByRooms(this.doc, rooms, fireZoneForm.m_fireZoneInfo, fireZoneForm.m_labelInfo, linePattern, lstOutWallData);
						fireZoneForm.SetTbNumber();
						continue;
					}
					catch (Exception)
					{
						fireZoneForm.Close();
						result = Autodesk.Revit.UI.Result.Succeeded;
					}
					return result;
				}
			}
			while (!areaCreator.CreateFireZoneByManualDrawNew(this.doc, fireZoneForm, linePattern));
			fireZoneForm.Close();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private static void DeleteAreaBorder(Autodesk.Revit.DB.Document doc)
		{
			Transaction transaction = new Transaction(doc);
			transaction.Start("DeleteElement");
			try
			{
				foreach (ModelCurve modelCurve in Common.FilterModelCurves(doc))
				{
					doc.Delete(modelCurve.Id);
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		public List<Curve> GetRoomSeparateLine()
		{
			List<Curve> list = new List<Curve>();
			foreach (Element element in new FilteredElementCollector(this.doc).OfCategory(BuiltInCategory.OST_RoomSeparationLines).WhereElementIsNotElementType().ToElements())
			{
				ModelCurve modelCurve = element as ModelCurve;
				if ((modelCurve.LineStyle as GraphicsStyle).Name == "<房间分隔>")
				{
					Curve curve = (modelCurve.Location as LocationCurve).Curve;
					list.Add(curve);
				}
			}
			return list;
		}

		public static WindowHandle _hWndRevit;

		public Document doc;
	}
}
